package JavaEE初阶;


class MyBlockingQueue{
    private volatile String[] data = new String[1000];
    //队列的起始位置
    private volatile  int head = 0;
    //队列的结束位置的下一个位置
    private volatile  int tail = 0;

    //队列中的元素个数
    private  volatile  int size = 0;

    //创建一个锁:
    public final Object locker = new Object();

    //提供核心方法
    //入队列：
    public void put(String elem) throws InterruptedException {
        //给put方法全加上锁:
        synchronized (locker){
            if(size == data.length){
               //如果是队列满，继续加入元素就会阻塞
                locker.wait();
            }
            data[tail] = elem;
            tail++;
            //如果tail++后到达了数组的末尾，此时就要让tail回到开头
            if(tail == data.length){
                tail = 0;
            }
            size++;

            //这个notify方法用来唤醒take方法中的wait
            locker.notify();
        }
    }

    //出队列：
    public  String take() throws InterruptedException {
        //给take方法全部加上锁：
        synchronized (locker){
            //队列为空,继续删除元素会阻塞
            if(size == 0){
                locker.wait();
            }

            //删除队首元素，进行返回
            String ret = data[head];
            head++;
            if(head == data.length){
                return null;
            }
            size--;
            //这个notify用来唤醒put方法中的wait方法
            locker.notify();
            return ret;
        }
    }

}
public class Demo06 {
    public static void main(String[] args) {
        MyBlockingQueue queue = new MyBlockingQueue();
        //生产者
        Thread t1 = new Thread(() ->{
            int num = 1;
            while(true){
                try {
                    queue.put(num+"");
                    System.out.println("生产元素"+ num);
                    num++;
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });


        //消费者
        Thread t2 = new Thread(() ->{
            while(true){
                try {
                    String result = queue.take();
                    System.out.println("消费元素" + result);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });
        t1.start();
        t2.start();
    }
}
